﻿module TinyJava.Ast

open System

type Program = ClassDecl list

and Id = string

and ClassDecl = Id * Option<Id> * FieldOrMethodDecl list

and FieldOrMethodDecl = 
| FieldDecl of SynType * VarNames
| MethodDecl of MethodRetType * Id * Formals list * Block

and MethodRetType = 
| RetType of SynType 
| Void

and VarNames = Id list

and Formals = SynType * Id

and SynType =
  | Int
  | Boolean
  | String
  | Identifier of string
  | Array of SynType


and Block = (VarDecl list) * (Statement list)

and VarDefs = (Id * Option<Expression>) list

and VarDecl = SynType * VarDefs

and Statement =
| Assign of Assignment
| Call of Call
| Return of Option<Expression>
| If of Expression * Statement * Option<Statement>
| While of Expression * Statement
| Break
| Continue
| Block of Block

and Assignment = Location * Expression

and Location =
| Id of Id
| ClassLoc of Expression * Id
| ArrayLoc of Expression * Expression

and Call = Method * Option<Actuals>

and Method =
| ImplicitMethod of Id
| MethodCall of Expression * Id

and Actuals = Expression list

and Expression =
| Location of Location
| Call of Call
| This
| DefaultConstructor of Id
| ArrayConstructor of SynType * Expression
| Length of Expression
| BinaryOp of Expression * BinaryOp * Expression
| UnaryOp of UnaryOp * Expression
| Literal of Literal

and BinaryOp =
| Plus of (SynType ref) //used for operator overload. The real value is initialized during type checking
| Minus
| Mul
| Div
| Mod
| And
| Or
| Less
| Leq
| Greater
| Geq
| Eq
| Neq

and UnaryOp = Sign | Not

and Literal = 
| IntLit of int
| StringLit of string
| Boolean of bool
| Null